package hero_info

import (
	"go_server/game_server/api/service/bag"
	"go_server/game_server/api/service/item"
	"go_server/game_server/constants"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/zinx/ziface"
	"math/rand"
	"strconv"
)

func (s *Hero_info_service) GM_GetHeros(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	return Hero_info_serviceObj.S2C_GetHeros(conn, roleid)
}

func (s *Hero_info_service) GM_AddHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if cid, err := strconv.Atoi(params[0]); err == nil {
		cfgids := make([]int32, 1)
		cfgids[0] = int32(cid)

		// 批量获取当前抽到的英雄的拥有状态
		heroStates, _ := Hero_info_serviceObj.ContainsHeroCfgIds(roleid, cfgids)
		heroInfo, exist := heroStates[int32(cid)] // 判断当前英雄是否拥有
		if !exist || !heroInfo {                  // 英雄不存在
			_, code := Hero_info_serviceObj.S2C_AddHero(conn, roleid, cfgids)
			return code
		}
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_DelHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_UpLvHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	msgC2S := &pb.UpLvHeroC2S{}
	if heroserid, err := strconv.Atoi(params[0]); err == nil {
		msgC2S.Heroserid = int32(heroserid)
		if hero, ok := Hero_info_serviceObj.LoadByRoleId(roleid).Heros[msgC2S.Heroserid]; ok {
			if cfgLevel, ok := config_manager.GetStcTableHero_SheetLevelConfig(hero.LvId); ok {
				consumes := hero.GetUpgradeLevelConsumes()

				its := consumes.Items.Elements()
				msgC2S.Items = make(map[int32]int32)
				needExp := cfgLevel.Consume
				for i := 0; i < len(its); i++ {
					id := its[i]
					if _, tok := msgC2S.Items[id]; !tok {
						msgC2S.Items[id] = 0
					}
					if d, dok := item.GetItemData(id); dok {
						needExp -= d.HeroExp
						msgC2S.Items[id]++
					}
					if needExp <= 0 {
						break
					}
				}
				bag.AddItemBatch(roleid, msgC2S.Items)
			}
		}
		return Hero_info_serviceObj.S2C_UpLvHero(conn, roleid, msgC2S)
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_UpStarHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	msgC2S := &pb.UpStarHeroC2S{}
	if heroserid, err := strconv.Atoi(params[0]); err == nil {
		msgC2S.Heroserid = int32(heroserid)
		if hero, ok := Hero_info_serviceObj.LoadByRoleId(roleid).Heros[msgC2S.Heroserid]; ok {
			if cfgStar, ok := config_manager.GetStcTableHero_SheetStarConfig(hero.StarId); ok {
				consumes := hero.GetUpgradeStarConsumes()
				fts := consumes.Fragments.Elements()
				msgC2S.Fragments = make(map[int32]int32)
				for i := 0; i < len(fts); i++ {
					msgC2S.Fragments[fts[i]] = cfgStar.Consume1
				}

				its := consumes.Items.Elements()
				msgC2S.Items = make(map[int32]int32)
				for i := 0; i < len(its); i++ {
					msgC2S.Items[its[i]] = cfgStar.Consume2
				}

				maps := util.MergeMaps(msgC2S.Fragments, msgC2S.Items)
				bag.AddItemBatch(roleid, maps)

				//for id, count := range msgC2S.Fragments {
				//	bag.AddItemSingle(roleid, id, count)
				//}
				//
				//for id, count := range msgC2S.Items {
				//	bag.AddItemSingle(roleid, id, count)
				//}
			}
		}
		return Hero_info_serviceObj.S2C_UpStarHero(conn, roleid, msgC2S)
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_UnlockHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if herocfgid, err := strconv.Atoi(params[0]); err == nil {
		msg := &pb.UnlockHeroC2S{Herocfgid: int32(herocfgid)}
		fragments := make(map[int32]int32)
		if cfg, ok := config_manager.GetStcTableHero_SheetHeroConfig(msg.Herocfgid); ok {
			bag.AddItemSingle(roleid, cfg.Unlockitemid, cfg.UnlockNum)
			fragments[cfg.Unlockitemid] = cfg.UnlockNum
		}
		msg.Fragments = fragments
		Hero_info_serviceObj.S2C_UnlockHero(conn, roleid, msg)
	}

	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_UniToExcFragments(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if herocfgid, err := strconv.Atoi(params[0]); err == nil {
		msg := &pb.UniToExcFragmentsC2S{Herocfgid: int32(herocfgid), Fragments: make(map[int32]int32)}
		if cfg, ok := config_manager.GetStcTableHero_SheetHeroConfig(msg.Herocfgid); ok {
			if items, k1 := item.GetUpgradeHeroItems(constants.Item_Upgrade_HerocCrrencyFragments, cfg.Quality); k1 {
				for id, _ := range items {
					msg.Fragments[id] = cfg.UnlockNum
				}
				bag.AddItemBatch(roleid, msg.Fragments)
			}
		}
		Hero_info_serviceObj.S2C_UniToExcFragments(conn, roleid, msg)
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_AddCfgIdHero(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if cid, err := strconv.Atoi(params[0]); err == nil {
		cfgids := make([]int32, 1)
		cfgids[0] = int32(cid)
		_, code := Hero_info_serviceObj.S2C_AddHero(conn, roleid, cfgids)
		return code
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_AddDefHeros(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	return Hero_info_serviceObj.S2C_AddDefHeros(conn, roleid)
}

func (s *Hero_info_service) GM_AddAllCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	cellcount := 1
	if len(params) > 0 {
		if count, err := strconv.Atoi(params[0]); err == nil {
			cellcount = count
		}
	}

	cells := make(map[int32]int32)
	cfgs := config_manager.GetTotal_StcTableHeroCell_SheetCell()
	for i := 0; i < len(cfgs); i++ {
		cells[cfgs[i]] = int32(cellcount)
	}
	Hero_info_serviceObj.S2C_AddCell(conn, roleid, cells)
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_AddCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if cfgid, err := strconv.Atoi(params[0]); err == nil {
		cells := make(map[int32]int32)
		cells[int32(cfgid)] = 1
		Hero_info_serviceObj.S2C_AddCell(conn, roleid, cells)
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_GetCells(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	Hero_info_serviceObj.S2C_GetCells(conn, roleid)
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_FuseCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	msgC2S := &pb.FuseCellC2S{}
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	tmpcells := make(map[int32][]int32)

	tmplv := int32(-1)
	if params != nil && len(params) > 0 {
		if v, err := strconv.Atoi(params[0]); err == nil {
			tmplv = int32(v)
		}
	}

	if hero != nil && hero.RoleCells != nil {
		for _, val := range hero.RoleCells {
			if cfg, ok := config_manager.GetStcTableHeroCell_SheetCell(val.CfgId); ok {
				if cfg.Fusion == celltype_Fusion {
					if val.Count > 0 && (tmplv == -1 || tmplv == val.Lv) {
						if _, t1 := tmpcells[val.Lv]; !t1 {
							tmpcells[val.Lv] = make([]int32, 0)
						}
						for i := 0; i < int(val.Count); i++ {
							tmpcells[val.Lv] = append(tmpcells[val.Lv], val.Serid)
						}
					}
				}
			}
		}
	}

	for _, serids := range tmpcells {
		if len(serids) >= Hero_info_serviceObj.GetFuseCellCount() {
			msgC2S.Cellserids = serids
			break
		}
	}

	Hero_info_serviceObj.S2C_FuseCell(conn, roleid, msgC2S)
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_OneKeyFuseAllCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	if lv, err := strconv.Atoi(params[0]); err == nil {
		msgC2S := &pb.FuseCellC2S{}
		msgC2S.OnekeyFuseOneof = &pb.FuseCellC2S_Fuselv{
			Fuselv: int32(lv),
		}
		Hero_info_serviceObj.S2C_FuseCell(conn, roleid, msgC2S)
	}
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_RecombinCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	msgC2S := &pb.RecombinCellC2S{}
	tmpcells := make(map[int32][]int32)
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	if hero != nil && hero.RoleCells != nil {
		for _, val := range hero.RoleCells {
			if cfg, ok := config_manager.GetStcTableHeroCell_SheetCell(val.CfgId); ok {
				if cfg.Fusion == celltype_Recombin {
					if val.Count > 0 {
						if _, t1 := tmpcells[val.Lv]; !t1 {
							tmpcells[val.Lv] = make([]int32, 0)
						}
						for i := 0; i < int(val.Count); i++ {
							tmpcells[val.Lv] = append(tmpcells[val.Lv], val.Serid)
						}
					}
				}
			}
		}
	}

	for _, serids := range tmpcells {
		if len(serids) >= Hero_info_serviceObj.GetRecombinCellCount() {
			msgC2S.Cellserids = serids
			break
		}
	}

	Hero_info_serviceObj.S2C_RecombinCell(conn, roleid, msgC2S)
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_EquipCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	msgC2S := &pb.EquipCellC2S{}
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	if hero != nil && hero.Heros != nil && hero.RoleCells != nil {
		hidx := rand.Intn(len(hero.Heros))
		rcidx := rand.Intn(len(hero.RoleCells))

		cx := int(0)
		rx := int(0)

		isend := false
		for heroserid, _ := range hero.Heros {
			for cellserid, _ := range hero.RoleCells {
				if cx >= hidx && rx >= rcidx {
					msgC2S.Heroserid = heroserid
					msgC2S.Cellserid = cellserid
					isend = true
					break
				}
				rx++
				if isend {
					break
				}
			}
			cx++
			if isend {
				break
			}
		}
	}

	rnd := util.NewRand()
	msgC2S.Cellidx = int32(rnd.Intn(int(Hero_info_serviceObj.GetHeroEquipCellMaxCount())))
	msgC2S.Cellidx = 1
	Hero_info_serviceObj.S2C_EquipCell(conn, roleid, msgC2S)
	return pb.ErrorCodeManager_SUCCESS
}

func (s *Hero_info_service) GM_UnEquipCell(conn ziface.IConnection, roleid int64, params []string) pb.ErrorCodeManager {
	hero := Hero_info_serviceObj.LoadByRoleId(roleid)
	if hero != nil && hero.Heros != nil {
		isend := false
		for _, hv := range hero.Heros {
			if hv.Cells != nil {
				for _, cv := range hv.Cells {
					msgC2S := &pb.UnEquipCellC2S{}
					msgC2S.Heroserids = make([]int32, 1)
					msgC2S.Heroserids[0] = hv.SerId

					msgC2S.Cellserids = make([]int32, 1)
					msgC2S.Cellserids[0] = cv.Serid
					Hero_info_serviceObj.S2C_UnEquipCell(conn, roleid, msgC2S)
					isend = true
					break
				}
			}
			if isend {
				break
			}
		}

	}

	return pb.ErrorCodeManager_SUCCESS
}
